#!/usr/bin/env python
import numpy as np
import itk
import scipy.ndimage as ndi
import sys
import os
import cv
import imageTools.ITKUtils.io as io
from . import anatomy_seg
from . import utils

def getPoints(img,i, mode="sagittal"):
    """return the mask of positive points in the ith slice of img"""
    if( mode.lower() == 'sagittal' ):
        return np.where(img[:,:,i] > 0)
    elif( mode.lower() == 'coronal' ):
        return np.where(img[:,i,:] > 0 )
    else:
        return np.where(img[i,:,:] > 0 )
def insertPoints(img,pnts,i, mode="sagittal"):
    """insert the points into the ith slice of img."""
    if( mode.lower() == 'sagittal' ):
        img[:,:,i] = pnts
    elif( mode.lower() == 'coronal' ):
        img[:,i,:] = pnts
    else:
        img[i,:,:] = pnts
    return img
def getNumSlices(img,mode="sagittal"):
    if( mode.lower() == 'sagittal' ):
        return img.shape[2]
    elif( mode.lower() == 'coronal' ):
        return img.shape[1]
    else:
        return img.shape[0]
def createZeroSlice(img,mode="sagittal"):
    if( mode.lower() == "sagittal" ):
        slice = np.zeros((img.shape[2],img.shape[0]),np.uint8)
    elif( mode.lower() == 'coronal' ):
        slice = np.zeros((img.shape[1],img.shape[0]),np.uint8)
    else:
        slice = np.zeros((img.shape[1],img.shape[0]),np.uint8)
    return slice
def lungExtraction(fname, tlow=-900, thigh=-200): 
    """extract a lung mask based on the tlow and thigh thresholds"""
    fout = utils.getModifiedFileName(fname,"lung")
    img = io.readImage(fname,returnITK=True,imgMode="float")
    btf = itk.BinaryThresholdImageFilter.IF3ISS3.New()
    btf.SetInput(img)
    btf.SetLowerThreshold(tlow)
    btf.SetUpperThreshold(thigh)
    ccf = itk.ConnectedComponentImageFilter.ISS3IUL3.New()
    ccf.SetInput(btf.GetOutput())
    ccf.SetFullyConnected(1)
    rcf = itk.RelabelComponentImageFilter.IUL3ISS3.New()
    rcf.SetInput(ccf.GetOutput())
    btf2 = itk.BinaryThresholdImageFilter.ISS3IUC3.New()
    btf2.SetInput(rcf.GetOutput())
    btf2.SetLowerThreshold(1)
    btf2.SetUpperThreshold(1)
    btf2.Update()
    writer = itk.ImageFileWriter.IUC3.New()
    writer.SetFileName(fout) 
    writer.SetInput(btf2.GetOutput())
    writer.Update()
    return fout

def applyMask(fname, mask):
    mask_img = io.readImage(mask)
    array = itk.PyBuffer.IF3.GetArrayFromImage(mask_img)
    mask = np.where( array > 0, 1,0).astype(np.uint8)
    img = io.readImage(fname) 
    img_array_1 = itk.PyBuffer.IF3.GetArrayFromImage(img)
    img_array = mask*img_array_1
    outputfile = utils.getModifiedFileName(fname,"masked")
    output_img = itk.PyBuffer.IF3.GetImageFromArray(img_array)
    io.writeImage(output_img, fname=outputfile, refimg=mask_img) 
    return outputfile

def compute_convex_hull(points) :
    storage = cv.CreateMemStorage(0)
    hull = cv.ConvexHull2 (points, storage, cv.CV_CLOCKWISE, 1)
    return hull 

def convexHullExtraction(fileName,mode="sagittal"):
    """"what is a good explanation?"""
    iimg = io.readImage(fileName,returnITK=True,imgMode="uchar")
    img = itk.PyBuffer.IUC3.GetArrayFromImage(iimg)
    img = np.where(img>0,1,0).astype(np.uint8)
    newImg = np.zeros(img.shape,np.uint8)
    print img.shape[0], img.shape[1], img.shape[2]
    for i in xrange(getNumSlices(newImg, mode=mode)):
        ns = getPoints(img, i, mode = mode )
        if len(ns[0]) > 0 :  
            ns = np.transpose(ns)
            hull = list(compute_convex_hull(ns)) 
            points = createZeroSlice(newImg, mode = mode )
            points = cv.fromarray(points)
            cv.FillConvexPoly(points, hull, 1)
            points = np.transpose(np.asarray(points))
            newImg = insertPoints(newImg,points,i, mode = mode )
    newImg = itk.PyBuffer.IUC3.GetImageFromArray(newImg)
    fout = utils.getModifiedFileName(fileName,"hull",mode)
    io.writeImage(newImg,fname=fout,refimg=iimg)
    return fout

def main():
  if (len(sys.argv) < 3):
     print ("Not enough arguments")
     sys.exit(1) 

  print sys.argv[1]
  inputFile = sys.argv[1]
  bodyImage =autonamy_seg.autonamyExtraction(inputFile, -300, 1000, 1)
  maskedImage = applyMask(inputFile, bodyImage)
  lungImage = lungExtraction(maskedImage) 
  convexHullExtraction(lungImage, mode= sys.argv[2])

if __name__ == '__main__':
    main()
 
